//
//  CMSChartsViewModel.m
//  CMSCharts
//
//  Created by symbio on 2023/2/17.
//

#import "CMSChartsViewModel.h"
#import <YYModel/YYModel.h>
#import "CMSChartsModel.h"
#import "CMSCharts-Swift.h"
#import "CMSChartsTimeShareModel.h"

@interface CMSChartsViewModel ()
@property (nonatomic, strong) NSArray<NSString *> *times;
@property (nonatomic, strong) NSArray<CandleChartDataEntry *> *candleChartDatas;

@property (nonatomic, strong) NSArray<CMSChartsModel *> *chartsModels;
@end
@implementation CMSChartsViewModel

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.isHorizontalScreen = NO;
    }
    return self;
}

- (NSArray<CMSChartsConfigModel *> *)visibleChartConfigs {
    NSMutableArray *muarr = [NSMutableArray array];
    for (CMSChartsConfigModel *model in self.chartConfigs) {
        if ((model.horizontal && self.isHorizontalScreen) || (model.vertical && !self.isHorizontalScreen)) {
            [muarr addObject:model];
        }
    }
    return muarr.copy;
}

- (NSArray<CMSChartsConfigModel *> *)invisibleChartConfigs {
    NSMutableArray *muarr = [NSMutableArray array];
    for (CMSChartsConfigModel *model in self.chartConfigs) {
        if ((!model.horizontal && self.isHorizontalScreen) || (!model.vertical && !self.isHorizontalScreen)) {
            [muarr addObject:model];
        }
    }
    return muarr.copy;
}

- (NSInteger)currentIndex {
    if (self.currentConfigModel == nil) {
        return -1;
    }
    
    if ([self.invisibleChartConfigs containsObject:self.currentConfigModel]) {
        return self.visibleChartConfigs.count;
    }
    
    return [self.visibleChartConfigs indexOfObject:self.currentConfigModel];
}

- (void)setArrChartData:(NSArray<NSDictionary *> *)arrChartData {
    _arrChartData = arrChartData;
    
    self.chartsModels = [NSArray yy_modelArrayWithClass:[CMSChartsModel class] json:arrChartData];
    
    [self reloadData];
}

- (void)setChartConfigs:(NSArray<CMSChartsConfigModel *> *)chartConfigs {
    _chartConfigs = chartConfigs;
    
    self.currentConfigModel = [self getSelectConfigModelWithChartConfigs:self.visibleChartConfigs];
}

/// 提取选择的配置
- (CMSChartsConfigModel *)getSelectConfigModelWithChartConfigs:(NSArray<CMSChartsConfigModel *> *)chartConfigs {
    CMSChartsConfigModel *model = nil;
    for (CMSChartsConfigModel *object in chartConfigs) {
        if (model == nil) {
            model = object;
        }
        if (model.select) {
            model = object;
            break;
        }
    }
    return model;
}

- (void)setCurrentConfigModel:(CMSChartsConfigModel *)currentConfigModel {
    _currentConfigModel = currentConfigModel;
    
    [self reloadData];
}

- (void)reloadData {
    
    if (self.currentConfigModel == nil || self.chartsModels.count <= 0) {
        return;
    }
    
    NSMutableArray *tempTimes = [NSMutableArray array];
    NSMutableArray *tempCandleChartDatas = [NSMutableArray array];
    
    [self.chartsModels enumerateObjectsUsingBlock:^(CMSChartsModel * _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
        [tempTimes addObject:model.updateTimeValue];
        [tempCandleChartDatas addObject:[[CandleChartDataEntry alloc] initWithX:idx + 0.5 shadowH:model.high.doubleValue shadowL:model.low.doubleValue open:model.open.doubleValue close:model.close.doubleValue]];
    }];
  
    self.times = tempTimes;
    self.candleChartDatas = tempCandleChartDatas;
    
    NSMutableArray *muarr = [NSMutableArray array];
    if (self.currentConfigModel.chartType == CMSChartsTypeTimeSharing) {
        [muarr addObject:[self getTimeSharingData]];
    } else if (self.currentConfigModel.chartType == CMSChartsTypeFiveDay) {
        [muarr addObject:[self getTimeSharingData]];
    } else if (self.currentConfigModel.chartType == CMSChartsTypeCandleStick) {
        [muarr addObject:[self getFirstContainerModel]];
    }
    for (int i = 0; i < self.currentConfigModel.subChartCount; i++) {
        CMSChartsContentModel *model = [CMSChartsContentModel new];
        switch (i) {
            case 0:
                model = [self getFirstContainerModel];
                break;
            case 1:
                model = [self getSecondContainerModel];
                break;
            case 2:
                model = [self getThirdContainerModel];
                break;
            default:
                model = [self getThirdContainerModel];
                break;
        }
        model.isAssistant = true;
        [muarr addObject:model];
    }
    
    self.containerModels = muarr.copy;
}

/// 获取分时数据
- (CMSChartsContentModel *)getTimeSharingData {
    
    NSArray *fsDatas = [[self getJsonWithName:@"fs"] valueForKeyPath:@"points.values"];
    NSArray<CMSChartsTimeShareModel *> *timeShareModels = [NSArray yy_modelArrayWithClass:[CMSChartsTimeShareModel class] json:fsDatas];
    
    CombinedChartData *data = [[CombinedChartData alloc] init];
    
    NSMutableArray *values = [[NSMutableArray alloc] init];
    NSMutableArray *muarr = [NSMutableArray array];
    for (int i = 0; i < timeShareModels.count; i++) {
        [values addObject:[[ChartDataEntry alloc] initWithX:i y:timeShareModels[i].now icon:nil]];
        [muarr addObject:[[ChartDataEntry alloc] initWithX:i y:timeShareModels[i].average]];
    }
    
    LineChartDataSet *set1 = [[LineChartDataSet alloc] initWithEntries:values label:@"DataSet 1"];
    
//    set1.drawIconsEnabled = NO;
    set1.drawValuesEnabled = NO;
//    set1.lineDashLengths = @[@5.f, @2.5f];
//    set1.highlightLineDashLengths = @[@5.f, @2.5f];
    [set1 setColor:UIColor.yellowColor];
//    [set1 setCircleColor:UIColor.blackColor];
    set1.lineWidth = 1.0;
//    set1.circleRadius = 3.0;
    set1.drawCirclesEnabled = NO;
//    set1.drawCircleHoleEnabled = NO;
//    set1.valueFont = [UIFont systemFontOfSize:9.f];
//    set1.formLineDashLengths = @[@5.f, @2.5f];
//    set1.formLineWidth = 1.0;
//    set1.formSize = 15.0;
    
    NSArray *gradientColors = @[
                                (id)[ChartColorTemplates colorFromString:@"#00ff0000"].CGColor,
                                (id)[ChartColorTemplates colorFromString:@"#ffff0000"].CGColor
                                ];
    CGGradientRef gradient = CGGradientCreateWithColors(nil, (CFArrayRef)gradientColors, nil);
    
    set1.fillAlpha = 1.f;
    set1.fill = [ChartFill fillWithLinearGradient:gradient angle:90.f];
    set1.drawFilledEnabled = YES;
    
    CGGradientRelease(gradient);
    
    NSMutableArray *dataSets = [[NSMutableArray alloc] init];
    /// 现价
    [dataSets addObject:set1];
    /// 均线
    [dataSets addObject:[CMSChartsTool getLineDataFor:muarr color:UIColor.redColor name:@""]];
    data.lineData = [[LineChartData alloc] initWithDataSets:dataSets];
    
    CMSChartsContentModel *containerModel = [[CMSChartsContentModel alloc] init];
    containerModel.chartData = data;
    containerModel.chartType = self.currentConfigModel.chartType;
    return containerModel;
}
- (id)getJsonWithName:(NSString *)name {
    NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"json"];
    NSData *data = [[NSData alloc] initWithContentsOfFile:path];
    return [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableContainers) error:NULL];
}

- (CMSChartsContentModel *)getThirdContainerModel {
    
    NSDictionary *dicKpiData = [MACD calcMACDForData:self.arrChartData andShort:12 andLong:26 andMid:9 withFiled:@"Close"];
    CombinedChartData *data = [self getMACDForDIF:dicKpiData[@"DIF"] DEA:dicKpiData[@"DEA"] MACD:dicKpiData[@"MACD"]];
    
    CMSChartsContentModel *containerModel = [[CMSChartsContentModel alloc] init];
    containerModel.chartData = data;
    containerModel.chartType = self.currentConfigModel.chartType;
    return containerModel;
}

- (CombinedChartData *)getMACDForDIF:(NSArray<NSNumber *> *)DIF
                                 DEA:(NSArray<NSNumber *> *)DEA
                                MACD:(NSArray<NSNumber *> *)MACD {
    NSMutableArray *yDIFValues = [NSMutableArray array];
    NSMutableArray *yDEAValues = [NSMutableArray array];
    NSMutableArray *yMACDValues = [NSMutableArray array];
    
    for (int i = 0; i < DIF.count; i++) {
        [yDIFValues addObject:[[ChartDataEntry alloc] initWithX:i y:[DIF[i] doubleValue]]];
    }
    
    for (int i = 0; i < DEA.count; i++) {
        [yDEAValues addObject:[[ChartDataEntry alloc] initWithX:i y:[DEA[i] doubleValue]]];
    }
    
    for (int i = 0; i < MACD.count; i++) {
        [yMACDValues addObject:[[BarChartDataEntry alloc] initWithX:i y:[MACD[i] doubleValue]]];
    }
    
    CombinedChartData *data = [[CombinedChartData alloc] init];
    
    data.lineData = [[LineChartData alloc] initWithDataSets:@[
        [MarketSetting setLineDataForValues:yDIFValues andColor:MarketSetting.dif_color withName:@"DIF"],
        [MarketSetting setLineDataForValues:yDEAValues andColor:MarketSetting.dea_color withName:@"DEA"]
    ]];
    
    data.barData = [[BarChartData alloc] initWithDataSets:@[
        [MarketSetting setBarCharSetForValues:yMACDValues withName:@"MACD"]
    ]];
    return data;
}

- (CMSChartsContentModel *)getSecondContainerModel {
    CombinedChartData *data = [[CombinedChartData alloc] init];
    
    NSMutableArray *muarr = [NSMutableArray array];

    NSArray *numbers = @[@5, @10, @15, @30];
    NSArray *colors = @[MarketSetting.dif_color, MarketSetting.dea_color, MarketSetting.kmacd_color, MarketSetting.kother_color];
    
    [numbers enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [muarr addObject:[self getLineDataWithNumber:[obj integerValue] color:colors[idx]]];
    }];
    data.lineData = [[LineChartData alloc] initWithDataSets:muarr];
    CMSChartsContentModel *containerModel = [[CMSChartsContentModel alloc] init];
    containerModel.chartData = data;
    containerModel.chartType = self.currentConfigModel.chartType;
    return containerModel;
}

- (LineChartDataSet *)getLineDataWithNumber:(NSInteger)number color:(UIColor *)color {
    NSMutableArray *muarr = [NSMutableArray array];
    [[self calcMAData:self.arrChartData andNumbner:number withFiled:@"Close"] enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [muarr addObject:[[ChartDataEntry alloc] initWithX:idx y:[obj doubleValue]]];
    }];
    return [CMSChartsTool getLineDataFor:muarr color:color name:@""];
}


- (CMSChartsContentModel *)getFirstContainerModel {
    CombinedChartData *data = [[CombinedChartData alloc] init];
    CandleChartDataSet *dataSet1 = [CMSChartsTool getCandleChartDataFor:self.candleChartDatas showCandleBar:YES increasingFilled:YES];
    
    NSMutableArray *muarr = [NSMutableArray array];
    CGFloat random = (arc4random() % 2) * 0.1 + 0.1;
    BOOL symbol = arc4random() % 2 == 0;
    for (CandleChartDataEntry *data in self.candleChartDatas) {
        CandleChartDataEntry *newData = data.copy;
        
        if (symbol) {
            newData.high += random;
            newData.low += random;
            newData.open += random;
            newData.close += random;
        } else {
            newData.high -= random;
            newData.low -= random;
            newData.open -= random;
            newData.close -= random;
        }
        
        [muarr addObject:newData];
    }
    
    CandleChartDataSet *dataSet2 = [CMSChartsTool getOverlapCandleChartDataFor:muarr showCandleBar:false];
//    data.candleData = [[CandleChartData alloc] initWithDataSets:@[dataSet1, dataSet2]];
    data.candleData = [[CandleChartData alloc] initWithDataSets:@[dataSet1]];
    
    CMSChartsContentModel *containerModel = [[CMSChartsContentModel alloc] init];
    containerModel.chartData = data;
    containerModel.chartType = self.currentConfigModel.chartType;
    return containerModel;
}

/// 计算MA均线
/// - Parameters:
///   - d: 数据源
///   - n: MA时间窗口 5,10,20,60
///   - f: 计算字段
/// - Returns: [Double]
- (NSArray<NSNumber *> *)calcMAData:(NSArray *)data andNumbner:(NSInteger)numbner withFiled:(NSString *)filed {
    
    if (filed.length <= 0) {
        return @[];
    }
    
    double sum = 0;
    NSMutableArray *muarr = [NSMutableArray array];
    
    for (int i = 0; i < data.count; i++) {
        if (i < numbner-1) {
            continue;
        }
        
        sum = 0;
        for (int j = 0; j < numbner; j++) {
            NSDictionary *item = data[i-j];
            double value = [item[filed] doubleValue];
            sum += value;
        }
        [muarr addObject:[NSNumber numberWithDouble:sum/numbner]];
    }
    
    return muarr;
}

@end
